<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>Menus in GTK#</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="GUI, GTK#, menus, C#, programming, Linux">
<meta name="description" content="In this part of the GTK# tutorial, we 
present menus.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container2">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content2">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Menus in GTK#</h1>

<p>
In this part of the GTK# programming tutorial, we will work with menus.
</p>

<p>
A <b>menubar</b> is one of the most common parts of the GUI application. 
It is a group of commands located in various menus. While in console applications 
you have to remember all those arcane commands, here we have most of the commands 
grouped into logical parts. These are accepted standards that further reduce the 
amount of time spending to learn a new application. 
</p>

<div class="big_hor">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* big_horizontal */
google_ad_slot = "2904953388";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>


<h2>Simple menu</h2>

<p>
In our first example, we will create a menubar with one file menu. 
The menu will have only one menu item. By selecting the item the application quits. 
</p>

<div class="codehead">simplemenu.cs</div> 
<pre class="code">
using Gtk;
using System;
 
class SharpApp : Window {
 

    public SharpApp() : base("Simple menu")
    {
        SetDefaultSize(250, 200);
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };
        
        MenuBar mb = new MenuBar();

        Menu filemenu = new Menu();
        MenuItem file = new MenuItem("File");
        file.Submenu = filemenu;
       
        MenuItem exit = new MenuItem("Exit");
        exit.Activated += OnActivated;
        filemenu.Append(exit);

        mb.Append(file);

        VBox vbox = new VBox(false, 2);
        vbox.PackStart(mb, false, false, 0);

        Add(vbox);

        ShowAll();
    }

    void OnActivated(object sender, EventArgs args)
    {
        Application.Quit();
    }

    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
This is a small example with minimal menubar functionality.
</p>

<pre class="explanation">
MenuBar mb = new MenuBar();
</pre>

<p>
<code>MenuBar</code> widget is created. 
</p>

<pre class="explanation">
Menu filemenu = new Menu();
MenuItem file = new MenuItem("File");
file.Submenu = filemenu;
</pre>

<p>
Toplevel <code>MenuItem</code> is created. 
</p>

<pre class="explanation">
MenuItem exit = new MenuItem("Exit");
exit.Activated += OnActivated;
filemenu.Append(exit);
</pre>

<p>
Exit <code>MenuItem</code> is created and appended to the
File <code>MenuItem</code>.
</p>

<pre class="explanation">
mb.Append(file);
</pre>

<p>
Toplevel <code>MenuItem</code> is appended to the <code>MenuBar</code>
widget. 
</p>

<pre class="explanation">
VBox vbox = new VBox(false, 2);
vbox.PackStart(mb, false, false, 0);
</pre>

<p>
Unlike in other toolkits, we have to take care of the layout management
ourselves. We put the menubar into the vertical box. 
</p>

<img src="/img/gui/sharpgtk/simplemenu.png" alt="Simple menu">
<div class="figure">Figure: Simple menu</div>


<h2>Image menu</h2>

<p>
In the next example, we will further explore the menus.
We will add images and accelerators to our menu items. 
<b>Accelerators</b> are keyboard shortcuts for activating a menu item. 
</p>

<div class="codehead">imagemenu.cs</div> 
<pre class="code">
using Gtk;
using System;
 
class SharpApp : Window {
 

    public SharpApp() : base("Image menu")
    {
        SetDefaultSize(250, 200);
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };
        
        MenuBar mb = new MenuBar();

        Menu filemenu = new Menu();
        MenuItem file = new MenuItem("File");
        file.Submenu = filemenu;
       
        AccelGroup agr = new AccelGroup();
        AddAccelGroup(agr);

        ImageMenuItem newi = new ImageMenuItem(Stock.New, agr);
        newi.AddAccelerator("activate", agr, new AccelKey(
            Gdk.Key.n, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
        filemenu.Append(newi);

        ImageMenuItem open = new ImageMenuItem(Stock.Open, agr);
        open.AddAccelerator("activate", agr, new AccelKey(
            Gdk.Key.n, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
        filemenu.Append(open);

        SeparatorMenuItem sep = new SeparatorMenuItem();
        filemenu.Append(sep);

        ImageMenuItem exit = new ImageMenuItem(Stock.Quit, agr);
        exit.AddAccelerator("activate", agr, new AccelKey(
            Gdk.Key.q, Gdk.ModifierType.ControlMask, AccelFlags.Visible));

        exit.Activated += OnActivated;
        filemenu.Append(exit);

        mb.Append(file);

        VBox vbox = new VBox(false, 2);
        vbox.PackStart(mb, false, false, 0);
        vbox.PackStart(new Label(), false, false, 0);

        Add(vbox);

        ShowAll();
    }

    void OnActivated(object sender, EventArgs args)
    {
        Application.Quit();
    }


    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
Our example shows a toplevel menu item with three sublevel menu items. Each of the
menu items has a image and an accelerator. The accelerator for the quit menu item
is active. 
</p>

<pre class="explanation">
AccelGroup agr = new AccelGroup();
AddAccelGroup(agr);
</pre>

<p>
To work with accelerators, we create a global <code>AccelGroup</code>
object. It will be used later.  
</p>

<pre class="explanation">
ImageMenuItem newi = new ImageMenuItem(Stock.New, agr);
</pre>

<p>
<code>ImageMenuItem</code> is created. The image comes from the stock
of images. 
</p>

<pre class="explanation">
exit.AddAccelerator("activate", agr, new AccelKey(
    Gdk.Key.q, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
</pre>

<p>
This creates an Ctrl+Q accelerator for the exit menu item. 
</p>

<pre class="explanation">
SeparatorMenuItem sep = new SeparatorMenuItem();
filemenu.Append(sep);
</pre>

<p>
These lines create a separator. It is used to group menu items
into logical groups. 
</p>


<img src="/img/gui/sharpgtk/imagemenu.png" alt="Image menu">
<div class="figure">Figure: Image menu</div>


<h2>CheckMenuItem</h2>

<p>
A <code>CheckMenuItem</code> is a menu item with a check box. 
It can be used to work with boolean properties. 
</p>

<div class="codehead">checkmenuitem.cs</div>
<pre class="code">
using Gtk;
using System;
 
class SharpApp : Window {
 
    private Statusbar statusbar;

    public SharpApp() : base("Check menu item")
    {
        SetDefaultSize(250, 200);
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };
        
        MenuBar mb = new MenuBar();

        Menu filemenu = new Menu();
        MenuItem file = new MenuItem("File");
        file.Submenu = filemenu;

        Menu viewmenu = new Menu();
        MenuItem view = new MenuItem("View");
        view.Submenu = viewmenu;

        CheckMenuItem stat = new CheckMenuItem("View Statusbar");
        stat.Toggle();
        stat.Toggled += OnStatusView;
        viewmenu.Append(stat);
       
        MenuItem exit = new MenuItem("Exit");
        exit.Activated += OnActivated;
        filemenu.Append(exit);

        mb.Append(file);
        mb.Append(view);

        statusbar = new Statusbar();
        statusbar.Push(1, "Ready");

        VBox vbox = new VBox(false, 2);
        vbox.PackStart(mb, false, false, 0);
        vbox.PackStart(new Label(), true, false, 0);
        vbox.PackStart(statusbar, false, false, 0);

        Add(vbox);

        ShowAll();
    }

    void OnStatusView(object sender, EventArgs args)
    {
        CheckMenuItem item = (CheckMenuItem) sender;

        if (item.Active) {
            statusbar.Show();
        } else {
            statusbar.Hide();
        }
    }
 
    void OnActivated(object sender, EventArgs args)
    {
        Application.Quit();
    }

    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
In our code example we show a check menu item. If the check box is activated,
the statusbar widget is shown. If not, the statusbar is hidden.  
</p>

<pre class="explanation">
CheckMenuItem stat = new CheckMenuItem("View Statusbar");
</pre>

<p>
<code>CheckMenuItem</code> widget is created. 
</p>

<pre class="explanation">
stat.Toggle();
</pre>

<p>
The <code>Toggle()</code> method checks/unchecks the 
check menu item. 
</p>

<pre class="explanation">
if (item.Active) {
    statusbar.Show();
} else {
    statusbar.Hide();
}
</pre>

<p>
Depending on the state of the <code>CheckMenuItem</code>, 
we show or hide the statusbar widget. 
</p>

<img src="/img/gui/sharpgtk/checkmenuitem.png" alt="CheckMenuItem">
<div class="figure">Figure: CheckMenuItem</div>


<h2>Submenu</h2>

<p>
Our final example demonstrates how to create a submenu in GTK#. 
</p>

<div class="codehead">submenu.cs</div>
<pre class="code">
using Gtk;
using System;
 
class SharpApp : Window {
 

    public SharpApp() : base("Submenu")
    {
        SetDefaultSize(250, 200);
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };
        
        MenuBar mb = new MenuBar();

        Menu filemenu = new Menu();
        MenuItem file = new MenuItem("File");
        file.Submenu = filemenu;

        // submenu creation
        Menu imenu = new Menu();

        MenuItem import = new MenuItem("Import");
        import.Submenu = imenu;

        MenuItem inews = new MenuItem("Import news feed...");
        MenuItem ibookmarks = new MenuItem("Import bookmarks...");
        MenuItem imail = new MenuItem("Import mail...");

        imenu.Append(inews);
        imenu.Append(ibookmarks);
        imenu.Append(imail);

        // exit menu item
        MenuItem exit = new MenuItem("Exit");
        exit.Activated += OnActivated;
       
        filemenu.Append(import);
        filemenu.Append(exit);
        mb.Append(file);

        VBox vbox = new VBox(false, 2);
        vbox.PackStart(mb, false, false, 0);
        vbox.PackStart(new Label(), false, false, 0);

        Add(vbox);

        ShowAll();
    }

    void OnActivated(object sender, EventArgs args)
    {
        Application.Quit();
    }

    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}
</pre>

<p>
Submenu creation. 
</p>

<pre class="explanation">
Menu imenu = new Menu();
</pre>

<p>
A submenu is a <code>Menu</code>. 
</p>

<pre class="explanation">
MenuItem import = new MenuItem("Import");
import.Submenu = imenu;
</pre>

<p>
It is a submenu of a menu item, which belogs to toplevel
file menu. 
</p>

<pre class="explanation">
MenuItem inews = new MenuItem("Import news feed...");
MenuItem ibookmarks = new MenuItem("Import bookmarks...");
MenuItem imail = new MenuItem("Import mail...");

imenu.Append(inews);
imenu.Append(ibookmarks);
imenu.Append(imail);
</pre>

<p>
Submenu has its own menu items. 
</p>

<img src="/img/gui/sharpgtk/submenu.png" alt="Submenu">
<div class="figure">Figure: Submenu</div>

<p>
In this chapter of the GTK# programming library, we showed, how to work with menus. 
</p>


<div class="center">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<br>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified January 24, 2009  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>
